package com.dragon.modules.yuegou.service.impl.act;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.yuegou.client.wechat_mini.request.QrcodeRequest;
import com.dragon.modules.yuegou.client.wechat_mini.service.MiniMultiService;
import com.dragon.modules.yuegou.entity.act.OffActivityEntity;
import com.dragon.modules.yuegou.entity.act.OffMemberActivityEntity;
import com.dragon.modules.yuegou.entity.act.OffPrizeEntity;
import com.dragon.modules.yuegou.entity.member.MemberEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantEntity;
import com.dragon.modules.yuegou.entity.order.OrderEntity;
import com.dragon.modules.yuegou.entity.product.SkuEntity;
import com.dragon.modules.yuegou.entity.product.SpuEntity;
import com.dragon.modules.yuegou.entity.product.StockEntity;
import com.dragon.modules.yuegou.enums.act.OffActivityStatus;
import com.dragon.modules.yuegou.enums.act.OffMemberActivityIsPrize;
import com.dragon.modules.yuegou.enums.act.OffPrizeStatus;
import com.dragon.modules.yuegou.enums.act.ParticStatus;
import com.dragon.modules.yuegou.enums.code.ActivityCode;
import com.dragon.modules.yuegou.enums.code.BusinessCode;
import com.dragon.modules.yuegou.enums.code.MemberCode;
import com.dragon.modules.yuegou.enums.code.ProductCode;
import com.dragon.modules.yuegou.enums.order.OrderStatus;
import com.dragon.modules.yuegou.enums.product.StockChangeType;
import com.dragon.modules.yuegou.mapper.act.OffActivityMapper;
import com.dragon.modules.yuegou.model.act.OffActivity;
import com.dragon.modules.yuegou.model.act.OffMemberActivity;
import com.dragon.modules.yuegou.model.act.OffPrize;
import com.dragon.modules.yuegou.model.merchant.Merchant;
import com.dragon.modules.yuegou.model.system.Document;
import com.dragon.modules.yuegou.query.act.OffActivityQuery;
import com.dragon.modules.yuegou.query.act.OffMemberActivityQuery;
import com.dragon.modules.yuegou.query.act.OffPrizeQuery;
import com.dragon.modules.yuegou.query.act.OffQuery;
import com.dragon.modules.yuegou.query.product.StockQuery;
import com.dragon.modules.yuegou.service.act.AnnualRaffleService;
import com.dragon.modules.yuegou.service.act.OffActivityService;
import com.dragon.modules.yuegou.service.act.OffMemberActivityService;
import com.dragon.modules.yuegou.service.act.OffPrizeService;
import com.dragon.modules.yuegou.service.busd.DistrictService;
import com.dragon.modules.yuegou.service.member.MemberService;
import com.dragon.modules.yuegou.service.merchant.MerchantService;
import com.dragon.modules.yuegou.service.order.OrderService;
import com.dragon.modules.yuegou.service.product.SkuService;
import com.dragon.modules.yuegou.service.product.SpuService;
import com.dragon.modules.yuegou.service.product.StockService;
import com.dragon.modules.yuegou.service.system.DocumentService;
import com.dragon.modules.yuegou.web.Check;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 线下抽奖活动表 服务实现
 *
 * @author pbuilder generated
 * @date 2019-11-19 10:57:52
 * @version 2.0
 */
@CacheConfig(cacheNames = OffActivityServiceImpl.OFF_ACTIVITY)
@Service("actOffActivityService")
public class OffActivityServiceImpl
		extends ServiceImpl<OffActivityMapper, OffActivityEntity>
		implements OffActivityService {
	protected static final String OFF_ACTIVITY = "Off_Activity";

	@Autowired
	private StockService stockService;
	
	@Autowired
	private OffPrizeService offPrizeService;
	
	@Autowired
	private SkuService skuService;
	
	@Autowired
	private SpuService spuService;
	
	@Autowired
	private MerchantService merchantService;
	
	@Autowired
	private OffMemberActivityService offMemberActivityService;
	
	@Autowired
	private OrderService orderService;
	
	@Autowired
	private MemberService memberService;
	
	@Autowired
	private DocumentService documentService;
	
	@Autowired
	private DistrictService districtService;
	@Autowired
	private AnnualRaffleService annualRaffleService;

	@Autowired
	private MiniMultiService miniMultiService;

	private Cache offActivityCache;

	@Autowired
	public void setOffActivityCacheManager(CacheManager cacheManager) {
		this.offActivityCache = cacheManager.getCache(OFF_ACTIVITY);
	}

	@Override
	public IPage<OffActivity> search(PageRequest page, OffQuery query) {
		IPage<OffActivityEntity> pageEntity = new Page<>(page.getPage(), page.getSize(), page.getCount());

		//创建查询条件
		OffActivityQuery activityQuery = new OffActivityQuery();
		activityQuery.setBusdId(query.getBusdId());
		activityQuery.name().like(query.getName());
		activityQuery.setStatus(query.getStatus());
		if (query.getDrawTimeE() != null && query.getDrawTimeS() != null) {
			activityQuery.drawTime().ge(query.getDrawTimeS());
			activityQuery.drawTime().le(query.getDrawTimeE());
		}
		QueryWrapper<OffActivityEntity> wrapper = activityQuery.toQueryWrapper();
		wrapper.orderByDesc(OffActivity.COL_CREATED_TIME);
		IPage<OffActivityEntity> iPage = baseMapper.selectPage(pageEntity,wrapper);
		return iPage.convert(OffActivity::new);
	}

	@Override
	@Transactional
	public void createActivity(OffActivity offActivity) {
		Check.notEmpty(offActivity.getBusdId(), BusinessCode.BUSDID_NOTNULL.getMessage());
		Check.notEmpty(offActivity.getName(), "活动名称不能为空");
		Check.length(offActivity.getName(), 0, 50, "活动名称不能超过五十字");
		Check.notEmpty(offActivity.getRule(), "活动规则不能为空");
		Check.length(offActivity.getName(), 0, 2000, "活动规则不超过两千字");
		Check.notEmpty(offActivity.getOffPrizes(), "活动奖品信息不能为空");
		//添加活动
		offActivity.setPublishStatus(true);
		offActivity.setStatus(OffActivityStatus.NOT_STARTED);
		offActivity.setDel(false);
		baseMapper.insert(offActivity);
		
		//获取集团配置的AppId
		String applicationId = districtService.getAppId(offActivity.getBusdId());
		
		
		//获取小程序跳转信息pages/detail/detail?activity=1198047155334070274
		QrcodeRequest request = new QrcodeRequest();
		request.setPath("lottery/luckDraw/luckDraw?activity="+offActivity.getId()+"&busdId="+offActivity.getBusdId());
		request.setIsHyaline(false);
		byte[] data = miniMultiService.wxaCode(applicationId).get(request);
		
		//转换上传文件到阿里云获取跳转Url
		InputStream inputStream = new ByteArrayInputStream(data); 
		Document document = documentService.upload(offActivity.getId(),"jpg",inputStream);
		offActivity.setUrl(document.getUrl());
		baseMapper.updateById(offActivity);
		
		//遍历添加奖品
		offActivity.getOffPrizes().forEach(offPrize -> {
			Check.notEmpty(offPrize.getGrade(), "奖品等级不能为空");
			Check.notEmpty(offPrize.getName(), "奖品名称不能为空");
			Check.notEmpty(offPrize.getImg(), "奖品图片不能为空");
			Check.positive(offPrize.getPrice(), "奖品单价必须是正数");
			Check.digits(offPrize.getSum(), 10, 2, "奖品单价保留两位小数");
			Check.positive(offPrize.getSum(), "奖品数量必须是正整数");
			Check.notEmpty(offPrize.getSkuId(), ProductCode.SKUID_NOTNULL.getMessage());
			
			//查询sku库存
			StockQuery stockQuery = new StockQuery();
			stockQuery.setSkuId(offPrize.getSkuId());
			List<StockEntity> stockList = stockService.list(stockQuery.toQueryWrapper());
			if (CollectionUtils.isNotEmpty(stockList)){
				throw new DragonException(ActivityCode.AWARD_NUM_IS_EXCEEDING_STANDARD);

			}
			StockEntity stock = stockList.get(0);
			//判断选中奖品库存是否足够
			if (stock.getStock() < offPrize.getSum()) {
				throw new DragonException(ActivityCode.AWARD_NUM_IS_EXCEEDING_STANDARD);
			}
			
			//减少奖品库存
			stockService.changeStock(offPrize.getSkuId(), -offPrize.getSum(), StockChangeType.EDIT);
			
			offPrize.setStatus(OffPrizeStatus.NOT_STARTED);
			offPrize.setActivityId(offActivity.getId());
			offPrize.setDel(false);
			
			offPrizeService.save(offPrize);
		});
	}

	@Override
	public OffActivity getActivity(String id) {
		//获得活动信息
		OffActivityEntity entity = getById(id);
		OffActivity offActivity = new OffActivity(entity);
		//获取奖品信息
		OffPrizeQuery prizeQuery = new OffPrizeQuery();
		prizeQuery.setActivityId(offActivity.getId());
		List<OffPrizeEntity> entities = offPrizeService.list(prizeQuery.toQueryWrapper());
		
		//获取商品信息
		List<OffPrize> prizes = entities.stream().map(OffPrize::new).collect(Collectors.toList());
		prizes.stream().forEach(prize -> {
			String skuId = prize.getSkuId();
			if (StringUtils.isNotEmpty(skuId)) {
				//查询sku信息
				SkuEntity sku = skuService.getById(skuId);
				if (sku != null && StringUtils.isNotEmpty(sku.getSpuId())) {
					prize.setAttrs(sku.getAttrs());
					//查询spu信息
					SpuEntity spu = spuService.getById(sku.getSpuId());
					prize.setBeginTime(spu.getBeginTime());
					prize.setEndTime(spu.getEndTime());
				}
				if (sku != null && StringUtils.isNotEmpty(sku.getMerchantId())) {
					//查询可核销商户信息
					MerchantEntity merchant = merchantService.getById(sku.getMerchantId());
					prize.setMerchantName(merchant.getMerchantName());
				}else {
					List<Merchant> merchantList = merchantService.listBySpuId(sku.getSpuId());
					if (CollectionUtils.isNotEmpty(merchantList)){
						String merchantName = merchantList.stream().map(Merchant::getMerchantName).collect(Collectors.joining(","));
						prize.setMerchantName(merchantName);
					}
				}
			}
		});
		
		offActivity.setOffPrizes(prizes);
		
		return offActivity;
	}

	@Override
	public OffActivity getActivityByCache(String activityId) {
		OffActivity offActivity = offActivityCache.get(activityId, OffActivity.class);
		if (null == offActivity) {//从数据库取
			offActivity = getActivity(activityId);
			offActivityCache.put(activityId,offActivity);
		}
		return offActivity;
	}

	@Override
	public OffActivity activityData(PageRequest page,String id,String mobile,OffMemberActivityIsPrize isPrize) {
		//查询活动信息
		OffActivityEntity entity = getById(id);
		OffActivity offActivity = new OffActivity(entity);
		//查询所有中奖的会员
		OffMemberActivityQuery memberActivityQuery = new OffMemberActivityQuery();
		memberActivityQuery.setActivityId(offActivity.getId());
		memberActivityQuery.setIsPrize(OffMemberActivityIsPrize.HAS_WON);
		List<OffMemberActivityEntity> list = offMemberActivityService.list(memberActivityQuery.toQueryWrapper());
		
		//判断是否已核销
		list.forEach(memberActivity -> {
			if (StringUtils.isNotEmpty(memberActivity.getOrderNo())) {
				OrderEntity order = orderService.getById(memberActivity.getOrderNo());
				if (order != null && order.getStatus().equals(OrderStatus.SUCCEED)) {
					//订单已完成，中奖状态设置为已领奖
					memberActivity.setIsPrize(OffMemberActivityIsPrize.RECEIVED);
					offMemberActivityService.updateById(memberActivity);
				}
			}
		});

		//查询会员参与信息
		OffMemberActivityQuery query = new OffMemberActivityQuery();
		query.setActivityId(id);
		query.memberMobile().like(mobile);
		if (isPrize != null) {
			query.setIsPrize(isPrize);
		}
		QueryWrapper<OffMemberActivityEntity> wrapper = query.toQueryWrapper();
		wrapper.orderByDesc(OffMemberActivityEntity.COL_IS_PRIZE);
		IPage<OffMemberActivityEntity> entityIPage = new Page<>(page.getPage(),page.getSize(),true);

		IPage<OffMemberActivityEntity> iPage = offMemberActivityService.page(entityIPage,wrapper);

		offActivity.setMemberActiveIpage(iPage.convert(OffMemberActivity::new));
		return offActivity;
	}

	@Override
	public void under(String id) {
		//获取活动信息
		OffActivityEntity offActivity = getById(id);
		//判断活动状态
		if (!offActivity.getStatus().equals(OffActivityStatus.NOT_STARTED)) {
			throw new DragonException(ActivityCode.UNDER_NOT_STARTED);
		}
		//修改活动上下架状态
		offActivity.setPublishStatus(false);
		
		baseMapper.updateById(offActivity);
	}

	@Override
	public OffActivity participate(String id, String memberId) {
		Check.notEmpty(id, "活动Id不能为空");
		Check.notEmpty(memberId, MemberCode.MEMBER_ID_IS_EMPTY.getMessage());
		//获取活动信息
		OffActivityEntity entity = getById(id);
		
		if (entity == null) {
			throw new DragonException(ActivityCode.ACTIVITY_NOT_EXIST);
		}
		OffActivity offActivity = new OffActivity(entity);
		//获取会员参与信息
		OffMemberActivityQuery memberActivityQuery = new OffMemberActivityQuery();
		memberActivityQuery.setActivityId(id);
		memberActivityQuery.setMemberId(memberId);
		List<OffMemberActivityEntity> memberActivityList = offMemberActivityService.list(memberActivityQuery.toQueryWrapper());

		//判断会员参与状态
		if (CollectionUtils.isNotEmpty(memberActivityList)){
			if (!offActivity.getStatus().equals(OffActivityStatus.OVER)) {
				//活动还未结束(未参与)
				offActivity.setParticStatus(ParticStatus.NOT_PARTIC);
			}else {
				//活动已结束(已结束)
				offActivity.setParticStatus(ParticStatus.OVER);
			}
		}else {
			OffMemberActivityEntity memberActivity = memberActivityList.get(0);
			if (!offActivity.getStatus().equals(OffActivityStatus.OVER)) {
				//活动还未结束(已参与)
				offActivity.setParticStatus(ParticStatus.ALREADY_INVOLVED);
			}else if(memberActivity.getIsPrize().equals(OffMemberActivityIsPrize.NOT_WON)){
				//活动已结束(已参与未中奖)
				offActivity.setParticStatus(ParticStatus.NOT_WON);
			}else {
				//活动已结束(已参与已中奖)
				offActivity.setParticStatus(ParticStatus.HAS_WON);
			}
		}
		return offActivity;
	}

	@Override
	public void joinActivity(String id, String memberId) {
		boolean isStart = annualRaffleService.isStartActivity(id);
		if(isStart){
			throw new DragonException(ActivityCode.ACTIVITY_ALREADY_START);
		}
		//获取活动信息
		OffActivity offActivity = getActivityByCache(id);
		if (null == offActivity) {
			throw new DragonException(ActivityCode.ACTIVITY_NOT_EXIST);
		} else {
			if (offActivity.getDel() == true || offActivity.getPublishStatus() == false) {
				throw new DragonException(ActivityCode.ACTIVITY_NOT_EXIST);
			}
		}

		//是否参加
		boolean isJoin = offMemberActivityService.isJoin(offActivity.getId(), memberId);
		if (isJoin) {
			throw new DragonException(ActivityCode.MEMBER_HAS_JOIN);
		}

		//获取会员信息
		MemberEntity member = memberService.getById(memberId);

		//插入会员参与信息
		OffMemberActivity offMemberActivity = new OffMemberActivity();
		offMemberActivity.setMemberId(member.getId());
		offMemberActivity.setMemberHead(member.getHeadImg());
		offMemberActivity.setMemberMobile(member.getMobile());
		offMemberActivity.setActivityId(id);
		offMemberActivity.setIsPrize(OffMemberActivityIsPrize.NOT_WON);
		offMemberActivityService.save(offMemberActivity);
	}

	@Override
	public OffActivity activityPrize(String id) {
		//获取活动信息
		OffActivityEntity entity = getById(id);
		
		//活动不存在
		if (entity == null || entity.getDel()) {
			throw new DragonException(ActivityCode.ACTIVITY_NOT_EXIST);
		}
		OffActivity offActivity = new OffActivity(entity);
		//获取奖品信息
		OffPrizeQuery offPrizeQuery = new OffPrizeQuery();
		offPrizeQuery.setActivityId(offActivity.getId());
		offPrizeQuery.setDel(false);
		List<OffPrizeEntity> list = offPrizeService.list(offPrizeQuery.toQueryWrapper());
		
		offActivity.setOffPrizes(list.stream().map(OffPrize::new).collect(Collectors.toList()));
		
		return offActivity;
	}

	@Override
	public List<OffPrize> startDraw(String id) {
		//获取活动信息
		OffActivityEntity offActivity = getById(id);
		
		//活动不存在
		if (offActivity == null || offActivity.getDel()) {
			throw new DragonException(ActivityCode.ACTIVITY_NOT_EXIST);
		}
		
		OffMemberActivityQuery memberActivityQuery = new OffMemberActivityQuery();
		memberActivityQuery.setActivityId(offActivity.getId());
		Long count = offMemberActivityService.count(memberActivityQuery.toQueryWrapper());
		
		//判断是否有会员参与活动
		if (count <= 0) {
			throw new DragonException(ActivityCode.NOT_PARTIC);
		}
		
		//活动为未开始修改为进行中
		if (offActivity.getStatus().equals(OffActivityStatus.NOT_STARTED)) {
			offActivity.setStatus(OffActivityStatus.ONGOING);
			offActivity.setDrawTime(LocalDateTime.now());
		}
		
		//修改活动状态
		baseMapper.updateById(offActivity);
		
		//获取活动下奖品列表
		OffPrizeQuery offPrizeQuery = new OffPrizeQuery();
		offPrizeQuery.setActivityId(offActivity.getId());
		offPrizeQuery.setDel(false);
		
		List<OffPrizeEntity> list = offPrizeService.list(offPrizeQuery.toQueryWrapper());
		
		return list.stream().map(OffPrize::new).collect(Collectors.toList());
	}

}